using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using System.Diagnostics;
using Uantek.Device.Communication.Models;
using Uantek.Device.Communication.Protocols.Interfaces;

namespace Uantek.Device.Communication.Protocols.Transports
{
    /// <summary>
    /// 通信传输基类
    /// </summary>
    public abstract class BaseCommunicationTransport : ICommunicationTransport
    {
        /// <summary>
        /// 日志记录器
        /// </summary>
        protected readonly ILogger? _logger;

        /// <summary>
        /// 连接参数
        /// </summary>
        protected Dictionary<string, object> _connectionParameters = new();

        /// <summary>
        /// 连接状态锁
        /// </summary>
        protected readonly object _connectionLock = new object();

        /// <summary>
        /// 发送锁
        /// </summary>
        protected readonly object _sendLock = new object();

        /// <summary>
        /// 接收缓冲区
        /// </summary>
        protected readonly ConcurrentQueue<byte[]> _receiveBuffer = new();

        /// <summary>
        /// 等待响应的任务
        /// </summary>
        protected readonly ConcurrentDictionary<string, TaskCompletionSource<byte[]>> _pendingRequests = new();

        /// <summary>
        /// 取消令牌源
        /// </summary>
        protected CancellationTokenSource? _cancellationTokenSource;

        /// <summary>
        /// 连接状态
        /// </summary>
        protected volatile bool _isConnected = false;

        /// <summary>
        /// 是否已释放
        /// </summary>
        protected volatile bool _disposed = false;

        /// <summary>
        /// 传输类型
        /// </summary>
        public abstract string TransportType { get; }

        /// <summary>
        /// 连接状态
        /// </summary>
        public virtual bool IsConnected 
        { 
            get 
            { 
                lock (_connectionLock)
                {
                    return _isConnected && !_disposed;
                }
            } 
        }

        /// <summary>
        /// 连接配置信息
        /// </summary>
        public virtual string ConnectionInfo { get; protected set; } = string.Empty;

        /// <summary>
        /// 数据接收事件
        /// </summary>
        public event EventHandler<byte[]>? DataReceived;

        /// <summary>
        /// 连接状态变化事件
        /// </summary>
        public event EventHandler<bool>? ConnectionStatusChanged;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger">日志记录器</param>
        protected BaseCommunicationTransport(ILogger? logger = null)
        {
            _logger = logger;
        }

        /// <summary>
        /// 连接到设备
        /// </summary>
        /// <param name="connectionParameters">连接参数</param>
        /// <returns>连接结果</returns>
        public virtual async Task<CommunicationResult> ConnectAsync(Dictionary<string, object> connectionParameters)
        {
            var stopwatch = Stopwatch.StartNew();
            try
            {
                LogDebug("开始连接，传输类型: {TransportType}", TransportType);

                if (_disposed)
                {
                    return CommunicationResult.CreateFailure("传输对象已释放", "ObjectDisposed");
                }

                lock (_connectionLock)
                {
                    if (_isConnected)
                    {
                        LogWarning("连接已存在，传输类型: {TransportType}", TransportType);
                        return CommunicationResult.CreateSuccess("连接已存在");
                    }
                }

                _connectionParameters = connectionParameters ?? new Dictionary<string, object>();
                _cancellationTokenSource = new CancellationTokenSource();

                // 调用具体实现的连接逻辑
                var result = await ConnectInternalAsync(_connectionParameters, _cancellationTokenSource.Token);

                if (result.Success)
                {
                    lock (_connectionLock)
                    {
                        _isConnected = true;
                    }

                    ConnectionInfo = BuildConnectionInfo(_connectionParameters);
                    
                    // 启动数据接收
                    _ = Task.Run(async () => await ReceiveDataLoopAsync(_cancellationTokenSource.Token));

                    // 触发连接状态变化事件
                    OnConnectionStatusChanged(true);

                    LogInformation("连接成功，传输类型: {TransportType}，连接信息: {ConnectionInfo}，耗时: {ElapsedMs}ms", 
                        TransportType, ConnectionInfo, stopwatch.ElapsedMilliseconds);
                }
                else
                {
                    LogError("连接失败，传输类型: {TransportType}，错误: {Message}", TransportType, result.Message);
                }

                result.ElapsedMilliseconds = stopwatch.ElapsedMilliseconds;
                return result;
            }
            catch (Exception ex)
            {
                LogError(ex, "连接时发生异常，传输类型: {TransportType}", TransportType);
                return CommunicationResult.CreateFailure($"连接异常: {ex.Message}", "ConnectionException", ex);
            }
            finally
            {
                stopwatch.Stop();
            }
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        /// <returns>断开结果</returns>
        public virtual async Task<CommunicationResult> DisconnectAsync()
        {
            var stopwatch = Stopwatch.StartNew();
            try
            {
                LogDebug("开始断开连接，传输类型: {TransportType}", TransportType);

                lock (_connectionLock)
                {
                    if (!_isConnected)
                    {
                        LogWarning("连接不存在，传输类型: {TransportType}", TransportType);
                        return CommunicationResult.CreateSuccess("连接不存在");
                    }

                    _isConnected = false;
                }

                // 取消所有等待的任务
                _cancellationTokenSource?.Cancel();

                // 清空待处理的请求
                foreach (var kvp in _pendingRequests.ToArray())
                {
                    if (_pendingRequests.TryRemove(kvp.Key, out var tcs))
                    {
                        tcs.TrySetCanceled();
                    }
                }

                // 调用具体实现的断开逻辑
                var result = await DisconnectInternalAsync();

                // 触发连接状态变化事件
                OnConnectionStatusChanged(false);

                LogInformation("断开连接成功，传输类型: {TransportType}，耗时: {ElapsedMs}ms", 
                    TransportType, stopwatch.ElapsedMilliseconds);

                result.ElapsedMilliseconds = stopwatch.ElapsedMilliseconds;
                return result;
            }
            catch (Exception ex)
            {
                LogError(ex, "断开连接时发生异常，传输类型: {TransportType}", TransportType);
                return CommunicationResult.CreateFailure($"断开连接异常: {ex.Message}", "DisconnectionException", ex);
            }
            finally
            {
                stopwatch.Stop();
            }
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="data">要发送的数据</param>
        /// <returns>发送结果</returns>
        public virtual async Task<CommunicationResult> SendDataAsync(byte[] data)
        {
            var stopwatch = Stopwatch.StartNew();
            try
            {
                LogDebug("开始发送数据，传输类型: {TransportType}，数据长度: {Length}", TransportType, data.Length);

                if (!IsConnected)
                {
                    return CommunicationResult.CreateFailure("未连接", "NotConnected");
                }

                if (data == null || data.Length == 0)
                {
                    return CommunicationResult.CreateFailure("数据为空", "EmptyData");
                }

                lock (_sendLock)
                {
                    // 调用具体实现的发送逻辑
                    var result = SendDataInternal(data);
                    
                    if (result.Success)
                    {
                        LogDebug("数据发送成功，传输类型: {TransportType}，数据长度: {Length}，耗时: {ElapsedMs}ms", 
                            TransportType, data.Length, stopwatch.ElapsedMilliseconds);
                    }
                    else
                    {
                        LogError("数据发送失败，传输类型: {TransportType}，错误: {Message}", TransportType, result.Message);
                    }

                    result.ElapsedMilliseconds = stopwatch.ElapsedMilliseconds;
                    return result;
                }
            }
            catch (Exception ex)
            {
                LogError(ex, "发送数据时发生异常，传输类型: {TransportType}", TransportType);
                return CommunicationResult.CreateFailure($"发送数据异常: {ex.Message}", "SendException", ex);
            }
            finally
            {
                stopwatch.Stop();
            }
        }

        /// <summary>
        /// 发送数据并等待响应
        /// </summary>
        /// <param name="data">要发送的数据</param>
        /// <param name="timeout">超时时间（毫秒）</param>
        /// <returns>响应数据</returns>
        public virtual async Task<CommunicationResult<byte[]>> SendAndReceiveAsync(byte[] data, int timeout = 5000)
        {
            var stopwatch = Stopwatch.StartNew();
            try
            {
                LogDebug("开始发送数据并等待响应，传输类型: {TransportType}，数据长度: {Length}，超时: {Timeout}ms", 
                    TransportType, data.Length, timeout);

                if (!IsConnected)
                {
                    return CommunicationResult<byte[]>.CreateFailure("未连接", "NotConnected");
                }

                if (data == null || data.Length == 0)
                {
                    return CommunicationResult<byte[]>.CreateFailure("数据为空", "EmptyData");
                }

                // 生成请求ID
                var requestId = Guid.NewGuid().ToString();
                var tcs = new TaskCompletionSource<byte[]>();
                _pendingRequests[requestId] = tcs;

                try
                {
                    // 发送数据
                    var sendResult = await SendDataAsync(data);
                    if (!sendResult.Success)
                    {
                        return CommunicationResult<byte[]>.CreateFailure(sendResult.Message, sendResult.ErrorCode, sendResult.Exception);
                    }

                    // 等待响应
                    using var cts = new CancellationTokenSource(timeout);
                    cts.Token.Register(() => tcs.TrySetCanceled());

                    var responseData = await tcs.Task;

                    LogDebug("发送数据并等待响应成功，传输类型: {TransportType}，响应长度: {Length}，耗时: {ElapsedMs}ms", 
                        TransportType, responseData.Length, stopwatch.ElapsedMilliseconds);

                    var result = CommunicationResult<byte[]>.CreateSuccess(responseData, "发送并接收数据成功");
                    result.ElapsedMilliseconds = stopwatch.ElapsedMilliseconds;
                    return result;
                }
                catch (OperationCanceledException)
                {
                    LogWarning("等待响应超时，传输类型: {TransportType}，超时: {Timeout}ms", TransportType, timeout);
                    return CommunicationResult<byte[]>.CreateFailure("等待响应超时", "ResponseTimeout");
                }
                finally
                {
                    _pendingRequests.TryRemove(requestId, out _);
                }
            }
            catch (Exception ex)
            {
                LogError(ex, "发送数据并等待响应时发生异常，传输类型: {TransportType}", TransportType);
                return CommunicationResult<byte[]>.CreateFailure($"发送并接收数据异常: {ex.Message}", "SendReceiveException", ex);
            }
            finally
            {
                stopwatch.Stop();
            }
        }

        /// <summary>
        /// 配置传输参数
        /// </summary>
        /// <param name="parameters">参数</param>
        /// <returns>配置结果</returns>
        public virtual async Task<CommunicationResult> ConfigureAsync(Dictionary<string, object> parameters)
        {
            try
            {
                LogDebug("开始配置传输参数，传输类型: {TransportType}", TransportType);

                if (parameters == null)
                {
                    return CommunicationResult.CreateFailure("参数不能为空", "NullParameters");
                }

                // 调用具体实现的配置逻辑
                var result = await ConfigureInternalAsync(parameters);

                if (result.Success)
                {
                    // 更新连接参数
                    foreach (var kvp in parameters)
                    {
                        _connectionParameters[kvp.Key] = kvp.Value;
                    }

                    LogDebug("配置传输参数成功，传输类型: {TransportType}", TransportType);
                }
                else
                {
                    LogError("配置传输参数失败，传输类型: {TransportType}，错误: {Message}", TransportType, result.Message);
                }

                return result;
            }
            catch (Exception ex)
            {
                LogError(ex, "配置传输参数时发生异常，传输类型: {TransportType}", TransportType);
                return CommunicationResult.CreateFailure($"配置参数异常: {ex.Message}", "ConfigurationException", ex);
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public virtual void Dispose()
        {
            if (_disposed) return;

            try
            {
                LogDebug("开始释放传输资源，传输类型: {TransportType}", TransportType);

                _disposed = true;

                // 断开连接
                _ = Task.Run(async () =>
                {
                    try
                    {
                        await DisconnectAsync();
                    }
                    catch (Exception ex)
                    {
                        LogError(ex, "释放资源时断开连接失败，传输类型: {TransportType}", TransportType);
                    }
                });

                // 释放取消令牌源
                _cancellationTokenSource?.Dispose();

                // 调用具体实现的释放逻辑
                DisposeInternal();

                LogDebug("传输资源释放完成，传输类型: {TransportType}", TransportType);
            }
            catch (Exception ex)
            {
                LogError(ex, "释放传输资源时发生异常，传输类型: {TransportType}", TransportType);
            }
        }

        #region 抽象方法 - 由子类实现

        /// <summary>
        /// 连接的具体实现
        /// </summary>
        /// <param name="connectionParameters">连接参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>连接结果</returns>
        protected abstract Task<CommunicationResult> ConnectInternalAsync(Dictionary<string, object> connectionParameters, CancellationToken cancellationToken);

        /// <summary>
        /// 断开连接的具体实现
        /// </summary>
        /// <returns>断开结果</returns>
        protected abstract Task<CommunicationResult> DisconnectInternalAsync();

        /// <summary>
        /// 发送数据的具体实现
        /// </summary>
        /// <param name="data">数据</param>
        /// <returns>发送结果</returns>
        protected abstract CommunicationResult SendDataInternal(byte[] data);

        /// <summary>
        /// 配置参数的具体实现
        /// </summary>
        /// <param name="parameters">参数</param>
        /// <returns>配置结果</returns>
        protected abstract Task<CommunicationResult> ConfigureInternalAsync(Dictionary<string, object> parameters);

        /// <summary>
        /// 数据接收循环
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>任务</returns>
        protected abstract Task ReceiveDataLoopAsync(CancellationToken cancellationToken);

        /// <summary>
        /// 构建连接信息
        /// </summary>
        /// <param name="connectionParameters">连接参数</param>
        /// <returns>连接信息</returns>
        protected abstract string BuildConnectionInfo(Dictionary<string, object> connectionParameters);

        /// <summary>
        /// 释放资源的具体实现
        /// </summary>
        protected abstract void DisposeInternal();

        #endregion

        #region 受保护的方法

        /// <summary>
        /// 触发数据接收事件
        /// </summary>
        /// <param name="data">接收到的数据</param>
        protected virtual void OnDataReceived(byte[] data)
        {
            try
            {
                LogDebug("收到数据，传输类型: {TransportType}，数据长度: {Length}", TransportType, data.Length);

                // 添加到接收缓冲区
                _receiveBuffer.Enqueue(data);

                // 检查是否有等待的请求
                if (_pendingRequests.Count > 0)
                {
                    var firstRequest = _pendingRequests.Values.FirstOrDefault();
                    if (firstRequest != null && !firstRequest.Task.IsCompleted)
                    {
                        firstRequest.TrySetResult(data);
                        return;
                    }
                }

                // 触发数据接收事件
                DataReceived?.Invoke(this, data);
            }
            catch (Exception ex)
            {
                LogError(ex, "处理接收数据时发生异常，传输类型: {TransportType}", TransportType);
            }
        }

        /// <summary>
        /// 触发连接状态变化事件
        /// </summary>
        /// <param name="isConnected">连接状态</param>
        protected virtual void OnConnectionStatusChanged(bool isConnected)
        {
            try
            {
                LogDebug("连接状态变化，传输类型: {TransportType}，状态: {Status}", TransportType, isConnected ? "已连接" : "已断开");
                ConnectionStatusChanged?.Invoke(this, isConnected);
            }
            catch (Exception ex)
            {
                LogError(ex, "触发连接状态变化事件时发生异常，传输类型: {TransportType}", TransportType);
            }
        }

        /// <summary>
        /// 获取参数值
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="parameters">参数字典</param>
        /// <param name="key">参数键</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns>参数值</returns>
        protected static T GetParameter<T>(Dictionary<string, object> parameters, string key, T defaultValue)
        {
            if (parameters.TryGetValue(key, out var value))
            {
                try
                {
                    return (T)Convert.ChangeType(value, typeof(T));
                }
                catch
                {
                    return defaultValue;
                }
            }
            return defaultValue;
        }

        /// <summary>
        /// 记录调试信息
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="args">参数</param>
        protected void LogDebug(string message, params object[] args)
        {
            _logger?.LogDebug(message, args);
        }

        /// <summary>
        /// 记录信息
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="args">参数</param>
        protected void LogInformation(string message, params object[] args)
        {
            _logger?.LogInformation(message, args);
        }

        /// <summary>
        /// 记录警告信息
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="args">参数</param>
        protected void LogWarning(string message, params object[] args)
        {
            _logger?.LogWarning(message, args);
        }

        /// <summary>
        /// 记录错误信息
        /// </summary>
        /// <param name="ex">异常</param>
        /// <param name="message">消息</param>
        /// <param name="args">参数</param>
        protected void LogError(Exception ex, string message, params object[] args)
        {
            _logger?.LogError(ex, message, args);
        }

        /// <summary>
        /// 记录错误信息
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="args">参数</param>
        protected void LogError(string message, params object[] args)
        {
            _logger?.LogError(message, args);
        }

        #endregion
    }
}